﻿using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.OpenApi.Models;
using StarsAdmin.Core.Attributes;
using Swashbuckle.AspNetCore.SwaggerGen;
using System.Collections.Concurrent;

namespace StarsAdmin.Web.Core.Filter
{
    /// <summary>
    /// 接口文档排序过滤器
    /// </summary>
    public class OrderTagsDocumentFilter : IDocumentFilter
    {
        public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
        {
            var orderTagList = new ConcurrentDictionary<string, int>();
            // 遍历所有的Api
            foreach (var apiDescription in context.ApiDescriptions)
            {
                var order = 0;
                // 获取当前ApiDescription的所有的ActionDescriptor转换为ControllerActionDescriptor
                var actionDescriptor = apiDescription.ActionDescriptor as ControllerActionDescriptor;
                // 获得所有ActionDescriptor的属性标记，并筛选出OrderAttribute属性标记
                var objOrderAttribute = actionDescriptor.EndpointMetadata.FirstOrDefault(x => x is OrderAttribute);
                // 获得OrderAttribute的值
                if (objOrderAttribute != null)
                {
                    var orderAttribute = objOrderAttribute as OrderAttribute;
                    order = orderAttribute.Value;
                }
                // 将数据添加到字典里
                orderTagList.TryAdd(actionDescriptor.ControllerName, order);
            }
            // 将swagger文档的按照Order值排序
            swaggerDoc.Tags = swaggerDoc.Tags
                                        .OrderBy(u => orderTagList.TryGetValue(u.Name, out int order) ? order : 0)
                                        .ThenBy(u => u.Name)
                                        .ToArray();
        }
    }
}